import sys
import os
import traceback
import select
import termios

def round_up_to_block_size(bytes, size, fill):
    r = len(bytes) % size
    if r:
        bytes.extend([fill]*(size - r))

def program_name():
    return os.path.basename(sys.argv[0])

def caller_name():
    return traceback.extract_stack()[-2][2]

def file_to_ints(file_obj):
    while True:
        r = file_obj.read(1)
        if not r:
            return
        yield ord(r)

def stdin_bytes():
    return list(file_to_ints(sys.stdin))

def take(n, iterable):
    for (i, c) in enumerate(iterable):
        if i == n:
            return
        else:
            yield c

def gen_chunks(size, iterable):
    out = []
    for i in iterable:
        out.append(i)
        if len(out) == size:
            yield out
            out = []
    if out:
        yield out

def high_byte(x):
    return (x >> 8) & 0xff

def low_byte(x):
    return x & 0xff

def form_word(h, l):
    return h*256 + l

def copy_file_forever(fout, fin):
    while 1:
        fout.write(fin.read())
        fout.flush()

def copy_files_forever(file_pairs):
    'copy_files_forever( [ (dst,src), (dst,src), ... ] )'
    dst_dict = {}
    for (dst, src) in file_pairs:
        dst_dict[src] = dst
    while True:
        for i in select.select(dst_dict.keys(), [], [])[0]:
            r = i.read(1)
            if not r:
                continue
            dst_dict[i].write(r)

def terminal_input_set(file_obj, echo=False):
    fds = [ file_obj.fileno() ]*2
    (new_attr, old_attr) = [ termios.tcgetattr(x) for x in fds ]
    new_attr[3] &= ~termios.ICANON
    if not echo:
        new_attr[3] &= ~termios.ECHO
    new_attr[6][termios.VMIN] = 1
    new_attr[6][termios.VTIME] = 0
    termios.tcsetattr(file_obj.fileno(), termios.TCSANOW, new_attr)

    sys.exitfunc = lambda : termios.tcsetattr(file_obj.fileno(),
                    termios.TCSAFLUSH, old_attr)

main_function_list = []

def main_function(func, default=False):
    main_function_list.append(func)
    return func

def main_multicall_dispatch(args):
    global main_function_list
    name_to_main = dict( (x.__name__.replace('_', '-'), x)
                        for x in main_function_list )
    try:
        main_func = name_to_main[program_name()]
    except KeyError:
        sys.stderr.write('program name "%s" is not supported, '
                         'must be one of: %s\n' %
                        (program_name(), name_to_main.keys()) )
        sys.exit(2)
    main_func(args)
